﻿using Autofac;
using Extensions.Aop;
using Repository;
using Repository.Impl;
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;

namespace Extensions.Extensions
{
    public class AutofacModuleRegister : Autofac.Module
    {
        //Autofac通过程序集批量依赖注入
        protected override void Load(ContainerBuilder builder)
        {
            #region 带有接口层的服务注入

            var basePath = AppContext.BaseDirectory;
            var servicesDllFile = Path.Combine(basePath, "Services.dll");
            var repositoryDllFile = Path.Combine(basePath, "Repository.dll");
            if (!(File.Exists(servicesDllFile) && File.Exists(repositoryDllFile)))
            {
                var msg = "Repository.dll和service.dll 丢失。";
                throw new Exception(msg);
            }

            //注册仓储
            builder.RegisterGeneric(typeof(BaseRepository<>)).As(typeof(IBaseRepository<>))
            .InstancePerDependency();

            ////全局注入aop
            List<Type> aops = new List<Type>();
            builder.RegisterType<AopCache>();
            builder.RegisterType<AopLog>();
            builder.RegisterType<AopBusiness>();
            aops.Add(typeof(AopLog));
            aops.Add(typeof(AopCache));
            aops.Add(typeof(AopBusiness));

            // 获取 Service.dll 程序集服务，并注册
            var assemblysServices = Assembly.LoadFrom(servicesDllFile);
            builder.RegisterAssemblyTypes(assemblysServices)
            .AsImplementedInterfaces()
            .PropertiesAutowired()  //注入属性
            .InstancePerDependency();
            //.EnableInterfaceInterceptors()//引用Autofac.Extras.DynamicProxy;
            //.InterceptedBy(aops.ToArray());//允许将拦截器服务的列表分配给注册。

            // 获取 Repository.dll 程序集服务，并注册
            var assemblysRepository = Assembly.LoadFrom(repositoryDllFile);
            builder.RegisterAssemblyTypes(assemblysRepository)
            .AsImplementedInterfaces()
            .PropertiesAutowired() //注入属性
            .InstancePerDependency();
            #endregion


            #region 没有接口层的服务层注入

            //因为没有接口层，所以不能实现解耦，只能用 Load 方法。
            //注意如果使用没有接口的服务，并想对其使用 AOP 拦截，就必须设置为虚方法
            //var assemblysServicesNoInterfaces = Assembly.Load("Blog.Core.Services");
            //builder.RegisterAssemblyTypes(assemblysServicesNoInterfaces);

            #endregion


            #region 没有接口的单独类，启用class代理拦截

            //只能注入该类中的虚方法，且必须是public
            //builder.RegisterAssemblyTypes(Assembly.GetAssembly(typeof(Love)))
            //    .EnableClassInterceptors()
            //    .InterceptedBy(cacheType.ToArray());
            #endregion


            #region 单独注册一个含有接口的类，启用interface代理拦截
            //不用虚方法
            //builder.RegisterType<SystemUsersService>().As<ISystemUsersService>()
            //   .AsImplementedInterfaces()
            //   .EnableInterfaceInterceptors()
            //   .InterceptedBy(typeof(AopBusiness));
            #endregion
        }
    }
}
